
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include "Debug.h"
#include "AntDefine.h"
#include "Helper.h"
#include "configParser.h"
 
using namespace std;
Helper * Helper::_instance = NULL;

Helper::Helper() 
{
	m_sConfFile = "";
	m_sIPAcl = "";
	m_iPort = 0;
	m_iwPort = 0;
	m_iThreads = 10;
	m_iDefaultTimer = 0;
}

Helper::~Helper()
{
	
}

Helper * Helper::Instance(const char *confFile)
{
	if (NULL == _instance) 
	{
		_instance = new Helper();
		if ( !_instance->Startup(confFile) ) {
			delete _instance; 
			_instance = NULL;
		}
	}
	return _instance;
}

void Helper::Release(bool bForce)
{
	if (_instance) 
	{
		if(bForce)
		{
			delete _instance; 
			_instance = NULL;
		}
	}
}

bool  Helper::Startup(const char *confFile)
{
	if(confFile != NULL)
		m_sConfFile  = confFile;
	if(m_sConfFile.length() < 1)
	{
		ERRO<<": no helper.conf be given!"<<endl;
		return false;
	}
	struct stat st;
	if (lstat(confFile, &st) != 0)
	{
		ERRO<<":"<<confFile<<" is not exist!"<<endl;
		return false;
	}

	configParser cfg;
	map <string, string > g_Confs;
	g_Confs = cfg.Parser(confFile);
	if(g_Confs.size() <= 0)
	{
		cerr<<"error to explain conf :"<< confFile <<endl;
		return false;
	}
       
        map <string , string >::iterator iter;
        for(iter=g_Confs.begin(); iter != g_Confs.end(); iter++)
        {
             cout<< iter->first.c_str()<<"="<<iter->second.c_str()<<endl;
        }

	if( g_Confs.find("ip_acl_config") != g_Confs.end())
		m_sIPAcl  = g_Confs["ip_acl_config"];

	if( g_Confs.find("port") != g_Confs.end())
	{
		string sport  = g_Confs["port"];
		m_iPort = atoi(sport.c_str());
	}
	else
		m_iPort = 4080;
	INFO<<"listen port = "<< m_iPort <<endl;

	if( g_Confs.find("wport") != g_Confs.end())
	{
		string sport  = g_Confs["wport"];
		m_iwPort = atoi(sport.c_str());
	}
	else
		m_iwPort = 0;

	if( g_Confs.find("threads") != g_Confs.end())
	{
		string sport  = g_Confs["threads"];
		m_iThreads = atoi(sport.c_str());
	}
	else
		m_iThreads = 10;
        int itype = 0;
	if( g_Confs.find("connection_type") != g_Confs.end())
	{
		string stype  = g_Confs["connection_type"];
                itype = atoi(stype.c_str());
	}

	if( g_Confs.find("defaultTimer") != g_Confs.end())
	{
		string st  = g_Confs["defaultTimer"];
		m_iDefaultTimer = atoi(st.c_str());
               if(m_iDefaultTimer < 0)
                   m_iDefaultTimer = 0;
	}
	return true;
}

int Helper :: Timer(long time)
{
        INFO<<time<<endl;
	return 0;
}

int Helper ::  Process(char *data, unsigned dlen,char **wbuf, unsigned &wsize, unsigned &wbytes, const char *ip)
{
	if(dlen <= 10)
	{  
		INFO<<data<<endl;
		data[dlen] = '\0';
		int len = atoi(data);
		cout<<"receive date ="<< len << endl;
		if((int) wsize < len)
			*wbuf = (char *)realloc(*wbuf, len + 4);
		if(*wbuf != NULL)
		{
			wbytes = len + 4; 
                        bcopy(&wbytes, *wbuf, 4);
			memset(*wbuf+4, 'a', len);
                        DEBUG2("should send length = ", wbytes);
		}         
	}   
        else
        {
                cout<<" receive length = "<< dlen << endl;
		if(*wbuf != NULL)
		{
                        bcopy(&dlen, *wbuf + 4,  4);
                        wbytes = 8;
			bcopy(&wbytes,  *wbuf, 4);
		}         
        }
        // build_return_message(wbuf, 0, wsize, wbytes);
	return 0;
}

int Helper :: build_return_message(char **wbuf, int retcode,unsigned &wsize, unsigned &wbytes)
{
        wbytes = 2*sizeof(int);
        DEBUG4("wsize=", wsize, "; wbytes=", wbytes );
        if(wsize < wbytes)
        {
DEBUG1("realloc(*wbuf, wbytes+1)");
                *wbuf = (char *)realloc(*wbuf, wbytes +1);
                if(*wbuf == NULL){
                        ERRO<<"can't malloc for write buffer !"<<endl;
                        wbytes = 0;
                        return  ANT_CONN_ERR_CLOSE;
                }
                wsize = wbytes + 1;
        }

        unsigned usedlen = 0;
DEBUG4("wbuf =", *wbuf,"; bcopy wbytes = ", wbytes);
        bcopy(&wbytes, *wbuf + usedlen, sizeof(unsigned int));            //str_length
        usedlen += sizeof(unsigned int);
DEBUG2("bcopy retcode = ", retcode);
        bcopy(&retcode, *wbuf + usedlen, sizeof(int));   // retcode
        return 0;
}

